package main
import (
	"fmt"
	"os"
	"errors"
)
//环形队列的实操
func main(){
	//先声明一个环形队列
	cqueue := &CircleQueue{
		maxSize : 5,
		head : 0,
		tail : 0,
	}
	var key int
	var val int
	for{
		fmt.Println("环形队列的实操：")
		fmt.Println("1、 ----入队----")
		fmt.Println("2、 ----出队----")
		fmt.Println("3、 ----显示----")
		fmt.Println("4、 ----退出----")
		fmt.Printf("请输入标号：")
		fmt.Scanln(&key)
		switch key{
		case 1:
			fmt.Printf("请输入入队值：")
			fmt.Scanln(&val)
			err := cqueue.Push(val)
			if err != nil{
				fmt.Println("push err :",err)
			}else{
				fmt.Println("push success!")
			}
		case 2:
			val,err := cqueue.Pop()
			if err != nil{
				fmt.Println("pop err :",err)
			}else{
				fmt.Println("pop success! pop val is:",val)
			}
		case 3:
			cqueue.Show()
		case 4:
			os.Exit(0)
	}
	}
	
	
}
//定义一个结构体来封装环形队列，队列的最大容量是数组容量-1，因为需要留一个空位作为 尾部标记位！
type CircleQueue struct{
	maxSize int
	array [5]int	////实际只能用4个位置，因为有一个位置拿来做尾部标志位
	head int	//指向队首，包含队首元素
	tail int	//指向队尾，不包含队尾元素，是队尾元素的下一个元素
}
//入队
func (this *CircleQueue) Push(val int)(err error){
	//先判断队列是否满了，满了就不能进了！
	if (this.tail + 1) % this.maxSize == this.head{
		return errors.New("队列已满!")
	}
	this.array[this.tail] = val
	this.tail = ( this.tail + 1 ) % this.maxSize
	return nil
}
//出队
func (this *CircleQueue) Pop() (val int,err error){
	//先判断队列是否为空
	if this.tail == this.head{ //头尾指针重叠就是空队列
		return -1,errors.New("队列是空的")
	}
	val = this.array[this.head]
	this.head = (this.head + 1) % this.maxSize
	return 
}
//输出队列数据
func (this *CircleQueue)Show(){
	size := (this.tail + this.maxSize - this.head) % this.maxSize  //获取队列中有多少个元素
	temphead := this.head  //临时保存头指针
	for i := 0;i < size;i++{
		fmt.Printf("array[%d]=%d\t",temphead,this.array[temphead])
		temphead = (temphead + 1) % this.maxSize
	}
	fmt.Println()
}